]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
altTab: fix app ordering in certain edge cases
authorDan Winship <danw@gnome.org>
Thu, 14 Jul 2011 21:23:16 +0000 (17:23 -0400)
committerOwen W. Taylor <otaylor@fishsoup.net>
Mon, 17 Oct 2011 16:54:03 +0000 (12:54 -0400)
Because we were sorting the Alt+Tab list by user_time rather than
stacking order / MRU, it was possible for the currently-focused window
to sometimes not be the first app in the list. Fix this by using
meta_display_get_tab_list() to get the proper MRU ordering of windows
on the current workspace, and then convert that to an ordered list of
apps.

https://bugzilla.gnome.org/show_bug.cgi?id=645026

js/ui/altTab.js

index 09ffcbb50d943706511791507dde9011b1476ff4..e17344f2885a3b243386d26333b6ecb9fe9f538e 100644 (file)
@@ -134,11 +134,40 @@ AltTabPopup.prototype = {
         }
     },
 
-    show : function(backward, binding, mask) {
+    _getAppLists: function() {
+        let tracker = Shell.WindowTracker.get_default();
         let appSys = Shell.AppSystem.get_default();
-        let apps = appSys.get_running ();
+        let allApps = appSys.get_running ();
+
+        let screen = global.screen;
+        let display = screen.get_display();
+        let windows = display.get_tab_list(Meta.TabList.NORMAL, screen,
+                                           screen.get_active_workspace());
+
+        // windows is only the windows on the current workspace. For
+        // each one, if it corresponds to an app we know, move that
+        // app from allApps to apps.
+        let apps = [];
+        for (let i = 0; i < windows.length && allApps.length != 0; i++) {
+            let app = tracker.get_window_app(windows[i]);
+            let index = allApps.indexOf(app);
+            if (index != -1) {
+                apps.push(app);
+                allApps.splice(index, 1);
+            }
+        }
+
+        // Now @apps is a list of apps on the current workspace, in
+        // standard Alt+Tab order (MRU except for minimized windows),
+        // and allApps is a list of apps that only appear on other
+        // workspaces, sorted by user_time, which is good enough.
+        return [apps, allApps];
+    },
 
-        if (!apps.length)
+    show : function(backward, binding, mask) {
+        let [localApps, otherApps] = this._getAppLists();
+
+        if (localApps.length == 0 && otherApps.length == 0)
             return false;
 
         if (!Main.pushModal(this.actor))
@@ -152,7 +181,7 @@ AltTabPopup.prototype = {
         this.actor.connect('button-press-event', Lang.bind(this, this._clickedOutside));
         this.actor.connect('scroll-event', Lang.bind(this, this._onScroll));
 
-        this._appSwitcher = new AppSwitcher(apps, this);
+        this._appSwitcher = new AppSwitcher(localApps, otherApps, this);
         this.actor.add_actor(this._appSwitcher.actor);
         this._appSwitcher.connect('item-activated', Lang.bind(this, this._appActivated));
         this._appSwitcher.connect('item-entered', Lang.bind(this, this._appEntered));
@@ -846,33 +875,32 @@ AppIcon.prototype = {
     }
 };
 
-function AppSwitcher(apps, altTabPopup) {
-    this._init(apps, altTabPopup);
+function AppSwitcher() {
+    this._init.apply(this, arguments);
 }
 
 AppSwitcher.prototype = {
     __proto__ : SwitcherList.prototype,
 
-    _init : function(apps, altTabPopup) {
+    _init : function(localApps, otherApps, altTabPopup) {
         SwitcherList.prototype._init.call(this, true);
 
-        // Construct the AppIcons, sort by time, add to the popup
+        // Construct the AppIcons, add to the popup
         let activeWorkspace = global.screen.get_active_workspace();
         let workspaceIcons = [];
         let otherIcons = [];
-        for (let i = 0; i < apps.length; i++) {
-            let appIcon = new AppIcon(apps[i]);
+        for (let i = 0; i < localApps.length; i++) {
+            let appIcon = new AppIcon(localApps[i]);
             // Cache the window list now; we don't handle dynamic changes here,
             // and we don't want to be continually retrieving it
             appIcon.cachedWindows = appIcon.app.get_windows();
-            if (this._hasWindowsOnWorkspace(appIcon, activeWorkspace))
-              workspaceIcons.push(appIcon);
-            else
-              otherIcons.push(appIcon);
+            workspaceIcons.push(appIcon);
+        }
+        for (let i = 0; i < otherApps.length; i++) {
+            let appIcon = new AppIcon(otherApps[i]);
+            appIcon.cachedWindows = appIcon.app.get_windows();
+            otherIcons.push(appIcon);
         }
-
-        workspaceIcons.sort(Lang.bind(this, this._sortAppIcon));
-        otherIcons.sort(Lang.bind(this, this._sortAppIcon));
 
         this.icons = [];
         this._arrows = [];
@@ -1012,19 +1040,6 @@ AppSwitcher.prototype = {
 
         if (appIcon.cachedWindows.length == 1)
             arrow.hide();
-    },
-
-    _hasWindowsOnWorkspace: function(appIcon, workspace) {
-        let windows = appIcon.cachedWindows;
-        for (let i = 0; i < windows.length; i++) {
-            if (windows[i].get_workspace() == workspace)
-                return true;
-        }
-        return false;
-    },
-
-    _sortAppIcon : function(appIcon1, appIcon2) {
-        return appIcon1.app.compare(appIcon2.app);
     }
 };